# 아래의 버전에 의존성이 있습니다.
# 다음의 버전으로 설치해 주세요.
# !pip install plotnine==0.5.0
# !pip install –upgrade pandas==0.23.4
# !pip install folium==0.5.0
# 그래프를 노트북 안에 그리기 위해 설정
%matplotlib inline
# 필요한 패키지와 라이브러리를 가져옴
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
# 그래프에서 마이너스 폰트 깨지는 문제에 대한 대처
mpl.rcParams['axes.unicode_minus'] = False
plt.rcParams["font.family"] = 'Malgun Gothic'
# Window에서는 dir을 사용합니다.
%ls data
import warnings
warnings.filterwarnings('ignore')
# warning 메시지 제거, warning 메시지는 라이브러리 업데이트나 사용법에 대한 안내 등이 있습니다.
# 코딩을 처음 시작할 때는 warning 메시지가 나오면 당황하실 수도 있어서 제거를 하고 보도록 합니다.
# warning 메시지는 제거하고 보셔도 되지만 Error 메시지를 꼭 고쳐주셔야 합니다.
warnings.filterwarnings('ignore', 'This pattern has match groups')
warnings.filterwarnings('ignore', 'The iterable function was deprecated in Matplotlib')
import pandas as pd
import numpy as np
from plotnine import *
import seaborn as sns
# 지도 시각화를 위해
import folium
# 한글 설정을 위해
sns.set(font='Noto Sans CJK JP')
# 노트북 안에서 그래프를 표시하기 위해
%matplotlib inline
import matplotlib.pyplot as plt
# Window 의 한글 폰트 설정
plt.rc('font',family='Malgun Gothic')
# Mac 의 한글 폰트 설정
#plt.rc('font', family='AppleGothic')
import requests
url = "https://www.data.go.kr/dataset/fileDownload.do?atchFileId=FILE_000000001543716&fileDetailSn=1" zipped = requests.get(url)
with open("./shop_info_downloaded.zip", "wb") as f:
f.write(zipped.content)
%ls -lh
shop_2019 = pd.read_csv('./data/소상공인시장진흥공단_상가업소정보_201906_01.csv')
shop_2019.head()
coffee = shop_2019[shop_2019['상권업종소분류명'].str.contains('커피')]
coffee.shape
coffee.columns
# 상호명으로 봤을 때 커피점이 12472개가 있다.
coffee['상호명'].unique().shape
coffee.loc[coffee['상호명'].str.contains('스타벅스'), '상호명'].unique()
coffee['시도명'].isnull().sum()
# 지난 데이터와 마찬가지로 서울과 부산만 있습니다.
# 다른 지역을 참고하고 싶다면 같은 폴더에 있는 다른 파일을 참고해 주세요.
coffee['시도명'].value_counts()
coffee['시군구명'].unique()
coffee['상권업종중분류명'].value_counts()
# (ggplot(shop_2018[:1000])
# + aes(x='경도', y='위도')
# + geom_point()
# + theme(text=element_text(family='NanumBarunGothic'))
# )
shop_2019[:1000].plot.scatter(x="경도", y="위도", grid="True")
df_seoul = shop_2019.loc[shop_2019['시도명'].str.startswith('서울')].copy()
df_seoul.shape
df_seoul.isnull().sum()
df_seoul['상권업종대분류명'].value_counts()
df_seoul.describe(include=np.object)
df_seoul[['위도', '경도']].describe(include=np.number)
sns.countplot(data=df_seoul, y="상권업종대분류명")
df_food = df_seoul.loc[df_seoul['상권업종대분류명'].str.contains('음식')]
df_food.shape
sns.countplot(data=df_food, y="상권업종중분류명")
df_fast_food = df_food.loc[df_food['상권업종중분류명'] == '패스트푸드']
df_fast_food.shape
df_food.columns
df_fast_food['상호명'].unique()
상호명에 키워드가 포함되고,
필터링 된 매장들에 대해 다시금 브랜드명을 부여해서
브랜드명 만으로 직접 비교 가능하게
df_seoul.loc[df_seoul['상호명'].str.contains('스타벅스|starbucks|STARBUCKS'), '상호명'].shape
df_seoul.loc[df_seoul['상호명'].str.contains('이디야|ediya|EDIYA'), '상호명'].shape
df_cafe = df_seoul[df_seoul['상호명'].str.contains('스타벅스|starbucks|STARBUCKS|이디야|ediya|EDIYA')]
df_cafe.shape
df_cafe.loc[df_cafe['상호명'].str.contains('스타벅스|starbucks|STARBUCKS'), '브랜드명'] = '스타벅스'
# ~은 not을 의미합니다. 스타벅스가 아닌 데이터는 이디야로 넣어주어도 되지만
# 아래 코드처럼 결측치를 이디야로 채워줘도 괜찮습니다.
# df_cafe.loc[~df_cafe['상호명'].str.contains('스타벅스|starbucks|STARBUCKS'), '브랜드명'] = '이디야'
df_cafe['브랜드명'] = df_cafe['브랜드명'].fillna('이디야')
df_cafe.loc[df_cafe['브랜드명'].isnull(), '상호명'].head()
df_cafe[['상호명','브랜드명']].head()
df_cafe['브랜드명'].value_counts()
geo_df = df_cafe
map = folium.Map(location=[geo_df['위도'].mean(), geo_df['경도'].mean()], zoom_start=12, tiles='Stamen Toner')
for n in geo_df.index:
# 팝업에 들어갈 텍스트를 지정해 줍니다.
popup_name = geo_df.loc[n, '상호명'] + ' - ' + geo_df.loc[n, '도로명주소']
# 브랜드명에 따라 아이콘 색상을 달리해서 찍어줍니다.
if geo_df.loc[n, '브랜드명'] == '스타벅스' :
icon_color = 'green'
else:
icon_color = 'blue'
# folium.CircleMarker 혹은 folium.features.CircleMarker 오류가 날 경우
# --> folium.vector_layer.CircleMarker 를 사용합니다.
folium.CircleMarker(
location=[geo_df.loc[n,'위도'], geo_df.loc[n, '경도']],
radius=3,
popup=popup_name,
color= icon_color,
fill=True,
fill_color=icon_color
).add_to(map)
map
df_cafe_brand = pd.DataFrame(
df_cafe.groupby(['시군구명', '브랜드명'])['상호명'].count()
).reset_index()
df_cafe_brand.columns = ['구', '브랜드명', '매장수']
df_cafe_brand
plt.figure(figsize=(24, 6))
sns.barplot(data=df_cafe_brand, x='구', y='매장수', hue='브랜드명')
df_cafe.groupby(['시군구명'])['상호명'].count()
df_cafe_gu = pd.DataFrame(df_cafe.groupby(['시군구명'])['상호명'].count())
df_cafe_gu.head()
import json
geo_path = 'data/seoul_municipalities_geo_simple.json'
geo_json = json.load(open(geo_path, encoding='utf-8'))
map = folium.Map(location=[geo_df['위도'].mean(), geo_df['경도'].mean()],
zoom_start=11)
map.choropleth(geo_data = geo_json,
data = df_cafe_gu['상호명'],
columns = [df_cafe_brand.index, df_cafe_gu['상호명']],
fill_color = 'Purples',
key_on = 'feature.properties.name',
fill_opacity=0.7,
line_opacity=0.2,
highlight=True)
for n in geo_df.index:
# 팝업에 들어갈 텍스트를 지정해 줍니다.
popup_name = geo_df.loc[n, '상호명'] + ' - ' + geo_df.loc[n, '도로명주소']
# 브랜드명에 따라 아이콘 색상을 달리해서 찍어줍니다.
if geo_df.loc[n, '브랜드명'] == '스타벅스' :
icon_color = 'green'
else:
icon_color = 'blue'
# folium.CircleMarker 혹은 folium.features.CircleMarker 오류가 날 경우
# --> folium.vector_layer.CircleMarker 를 사용합니다.
folium.CircleMarker(
location=[geo_df.loc[n,'위도'], geo_df.loc[n, '경도']],
radius=3,
popup=popup_name,
color= icon_color,
fill=True,
fill_color=icon_color
).add_to(map)
map
df_cafe_temp = df_cafe[df_cafe['브랜드명'] == '스타벅스']
df_cafe_starbucks = pd.DataFrame(df_cafe_temp.groupby(['시군구명'])['상호명'].count())
df_cafe_starbucks.columns = ['매장수']
df_cafe_starbucks.head()
map = folium.Map(location=[geo_df['위도'].mean(), geo_df['경도'].mean()],
zoom_start=11, tiles='Stamen Toner')
map.choropleth(geo_data = geo_json,
data = df_cafe_starbucks['매장수'],
columns = [df_cafe_starbucks.index, df_cafe_starbucks['매장수']],
fill_color = 'YlGn',
key_on = 'feature.properties.name',
fill_opacity=0.7,
line_opacity=0.2,
highlight=True)
for n in geo_df.index:
# 팝업에 들어갈 텍스트를 지정해 줍니다.
popup_name = geo_df.loc[n, '상호명'] + ' - ' + geo_df.loc[n, '도로명주소']
# 브랜드명에 따라 아이콘 색상을 달리해서 찍어줍니다.
if geo_df.loc[n, '브랜드명'] == '스타벅스' :
icon_color = 'green'
# folium.CircleMarker 혹은 folium.features.CircleMarker 오류가 날 경우
# --> folium.vector_layer.CircleMarker 를 사용합니다.
folium.CircleMarker(
location=[geo_df.loc[n,'위도'], geo_df.loc[n, '경도']],
radius=3,
popup=popup_name,
color= icon_color,
fill=True,
fill_color=icon_color
).add_to(map)
map
df_cafe_temp = df_cafe[df_cafe['브랜드명'] == '이디야']
df_cafe_ediya = pd.DataFrame(df_cafe_temp.groupby(['시군구명'])['상호명'].count())
df_cafe_ediya.columns = ['매장수']
df_cafe_ediya.head()
map = folium.Map(location=[geo_df['위도'].mean(), geo_df['경도'].mean()],
zoom_start=11, tiles='Stamen Toner')
map.choropleth(geo_data = geo_json,
data = df_cafe_ediya['매장수'],
columns = [df_cafe_ediya.index, df_cafe_ediya['매장수']],
fill_color = 'PuBu',
key_on = 'feature.properties.name',
fill_opacity=0.7,
line_opacity=0.2,
highlight=True)
for n in geo_df.index:
# 팝업에 들어갈 텍스트를 지정해 줍니다.
popup_name = geo_df.loc[n, '상호명'] + ' - ' + geo_df.loc[n, '도로명주소']
# 브랜드명에 따라 아이콘 색상을 달리해서 찍어줍니다.
if geo_df.loc[n, '브랜드명'] == '이디야' :
icon_color = 'blue'
# folium.CircleMarker 혹은 folium.features.CircleMarker 오류가 날 경우
# --> folium.vector_layer.CircleMarker 를 사용합니다.
folium.CircleMarker(
location=[geo_df.loc[n,'위도'], geo_df.loc[n, '경도']],
radius=3,
popup=popup_name,
color= icon_color,
fill=True,
fill_color=icon_color
).add_to(map)
map

df_cafe_brand.head()
df_cafe_brand_vs = df_cafe_brand.pivot_table(index='구',
columns='브랜드명',
values='매장수')
df_cafe_brand_vs.columns = ['스타벅스', '이디야']
df_cafe_brand_vs.head()
df_cafe_brand_vs['매장수비교'] = df_cafe_brand_vs.apply( \
lambda x : 1 if x['스타벅스'] > x['이디야'] else 0, axis=1)
df_cafe_brand_vs.head()
lng_list = []
lat_list = []
for gu in df_cafe_brand_vs.index:
lat = df_cafe.loc[df_cafe['시군구명'] == gu, '위도'].mean()
lng = df_cafe.loc[df_cafe['시군구명'] == gu, '경도'].mean()
lat_list.append(lat)
lng_list.append(lng)
df_cafe_brand_vs['위도'] = lat_list
df_cafe_brand_vs['경도'] = lng_list
df_cafe_brand_vs.head()
# CircleMarker의 radius 지정시 다음과 같은 타입오류가 나서 float type 으로 변경
# TypeError: Object of type 'int64' is not JSON serializable
df_cafe_brand_vs['스타벅스'] = df_cafe_brand_vs['스타벅스'].astype(float)
df_cafe_brand_vs['이디야'] = df_cafe_brand_vs['이디야'].astype(float)
df_cafe_brand_vs.info()
map = folium.Map(location=[geo_df['위도'].mean(), geo_df['경도'].mean()],
zoom_start=11, tiles='Stamen Toner')
map.choropleth(geo_data = geo_json,
data = df_cafe_brand_vs['매장수비교'],
columns = [df_cafe_brand_vs.index,
df_cafe_brand_vs['매장수비교']],
fill_color = 'BuGn',
key_on = 'feature.properties.name',
fill_opacity=0.7,
line_opacity=0.2,
highlight=True)
for gu in df_cafe_brand_vs.index:
for cafe in ['스타벅스', '이디야']:
cafe_count = df_cafe_brand_vs.loc[gu, cafe]
msg = f'{gu} {cafe} 매장수 : {cafe_count:.0f}'
icon_color = 'blue'
if cafe == '스타벅스':
icon_color = 'green'
# folium.CircleMarker 혹은 folium.features.CircleMarker 오류가 날 경우
# --> folium.vector_layer.CircleMarker 를 사용합니다.
folium.CircleMarker(
location = [df_cafe_brand_vs.loc[gu,'위도'],
df_cafe_brand_vs.loc[gu, '경도']],
radius = cafe_count,
color = icon_color,
popup = msg,
fill = True,
fill_color = icon_color
).add_to(map)
map